home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MIDICraft's MIDINET CD-ROM
/
MIDICraft's MIDINET CD-ROM.iso
/
DOSUTILS
/
KORG
/
SENDI3.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-30
|
14KB
|
660 lines
// sendi3: (c) Günter Nagler 1996
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "sb.hpp"
#include "korg.hpp"
#include "filei3.hpp"
#include <dir.h>
Soundcard* card = 0;
char* inputname = 0;
unsigned char data[5000];
int len = 0;
int aborted = 0;
// convert into 7 bit data and send
int senddumpdata(Soundcard* card, FILE* f, long pos, long len)
{
if (!f || len <= 0 || !card)
return 0;
fseek(f, pos, SEEK_SET);
if (ftell(f) != pos)
return 0;
unsigned char data8[7];
int datalen = 0;
long sum = 0;
fprintf(stderr, "0%% \r");
while (sum < len)
{
if (kbhit() && getch() == 27)
{
fprintf(stderr, "send aborted\n");
aborted = 1;
data[0] = 0xf7;
if (!card->play(data, 1))
fprintf(stderr, "error: data byte %02X not sent\n");
return 0;
}
if (datalen + 8 > sizeof(data))
{
if (card->play(data, datalen) != datalen)
{
fprintf(stderr, "error while sending data\n");
break;
}
fprintf(stderr, "%d%% \r", (int)((sum * 100)/len));
datalen = 0;
}
int n = fread(data8, 1, 7, f);
if (n <= 0)
break;
sum += n;
n = code7to8(data8, n, data+datalen);
datalen += n;
}
card->play(data, datalen);
fprintf(stderr, "100%%\r");
return len == sum;
}
int sendpcgdump(char* pcgfilename)
{
FILE* f = fopen(pcgfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x4c;
rewind(f);
PCGHEAD head;
if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.b1.adr != 0x58)
{
fprintf(stderr, "this is not a KORG PCG file (or a bad one)\n");
return 0;
}
printf("sending %s to KORG ...\n", inputname);
card->play(data, 5);
if (!senddumpdata(card, f, head.progdata.adr, head.progdata.len))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7; // eox
card->play(data, 1);
fclose(f);
return 1;
}
int sendstydump(char* styfilename)
{
FILE* f = fopen(styfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x65;
rewind(f);
STYHEAD head;
if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.stylenames.adr != 0x20)
{
fprintf(stderr, "this is not a KORG STY file (or a bad one)\n");
return 0;
}
fseek(f, 0, SEEK_END);
long flen = ftell(f);
printf("sending %s to KORG ...\n", inputname);
card->play(data, 5);
long datapos = head.styletable.adr;
if (!senddumpdata(card, f, datapos, flen-datapos))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7;
card->play(data, 1);
fclose(f);
return 1;
}
int sendarrdump(char* arrfilename)
{
FILE* f = fopen(arrfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x64;
rewind(f);
ARRHEAD head;
if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.arrnames.adr != 0x20)
{
fprintf(stderr, "this is not a KORG ARR file (or a bad one)\n");
return 0;
}
printf("sending %s to KORG ...\n", inputname);
card->play(data, 5);
if (!senddumpdata(card, f, head.arrdata.adr, head.arrdata.len))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7;
card->play(data, 1);
fclose(f);
return 1;
}
int sendbsqdump(char* bsqfilename)
{
FILE* f = fopen(bsqfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x66;
rewind(f);
BSQHEAD head;
if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0)
{
fprintf(stderr, "this is not a KORG BSQ file (or a bad one)\n");
return 0;
}
fseek(f, 0, SEEK_END);
long flen = ftell(f);
long steps = (flen - 2308) >> 4;
if (steps == 0)
printf("%s is empty backing sequence\n", inputname);
data[5] = (steps & 0x7f);
data[6] = (steps >> 7);
printf("sending %s to KORG ...\n", inputname);
card->play(data, 7);
long datapos = 0x10;
if (!senddumpdata(card, f, datapos, flen-datapos))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7;
card->play(data, 1);
fclose(f);
return 1;
}
int sendsngdump(char* sngfilename)
{
FILE* f = fopen(sngfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x48;
rewind(f);
SNGHEAD head;
if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0)
{
fprintf(stderr, "this is not a KORG SNG file (or a bad one)\n");
return 0;
}
fseek(f, 0, SEEK_END);
long flen = ftell(f);
long steps = (flen - 3718) >> 4;
if (steps == 0)
printf("%s is empty song\n", inputname);
data[5] = (steps & 0x7f);
data[6] = (steps >> 7);
printf("sending %s to KORG ...\n", inputname);
card->play(data, 7);
long datapos = 0x10;
if (!senddumpdata(card, f, datapos, flen-datapos))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7;
card->play(data, 1);
fclose(f);
return 1;
}
int sendglbdump(char* glbfilename)
{
FILE* f = fopen(glbfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x51;
rewind(f);
fseek(f, 0, SEEK_END);
long flen = ftell(f);
if (flen != 28)
{
fprintf(stderr, "this is not a KORG GLB file (or a bad one)\n");
return 0;
}
printf("sending %s to KORG ...\n", inputname);
card->play(data, 5);
if (!senddumpdata(card, f, 0, flen))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7;
card->play(data, 1);
fclose(f);
return 1;
}
int senddktdump(char* dktfilename)
{
FILE* f = fopen(dktfilename, "rb");
if (!f)
return 0;
data[0] = 0xf0;
data[1] = 0x42;
data[2] = 0x30;
data[3] = 0x39;
data[4] = 0x52;
rewind(f);
fseek(f, 0, SEEK_END);
long flen = ftell(f);
if (flen != 840)
{
fprintf(stderr, "this is not a KORG DKT file (or a bad one)\n");
return 0;
}
printf("sending %s to KORG ...\n", inputname);
card->play(data, 5);
if (!senddumpdata(card, f, 0, flen))
{
if (!aborted)
fprintf(stderr, "read error or file too short\n");
return 0;
}
data[0] = 0xf7;
card->play(data, 1);
fclose(f);
return 1;
}
void checkresponse()
{
#define RETRY 100
card->startinput();
for (long i = 0; i < RETRY; i++)
if (card->hear(data, 1))
break;
if (i == RETRY)
fprintf(stderr, "Warning: no response from KORG. Transfer might not work.\n");
else
fprintf(stderr, "KORG responded\n");
card->stopinput();
}
char* getext(char* filename)
{
char* ext = strrchr(filename, '.');
if (ext)
return ext+1;
return filename + strlen(filename);
}
int senddump(char* filename)
{
int ret;
inputname = filename;
char* ext = getext(filename);
if (!*ext)
return 0;
if (stricmp(ext, "pcg") == 0)
{
ret = sendpcgdump(filename);
}
else if (stricmp(ext, "sty") == 0)
{
ret = sendstydump(filename);
}
else if (stricmp(ext, "arr") == 0)
{
ret = sendarrdump(filename);
}
else if (stricmp(ext, "bsq") == 0)
{
ret = sendbsqdump(filename);
}
else if (stricmp(ext, "sng") == 0)
{
ret = sendsngdump(filename);
}
else if (stricmp(ext, "glb") == 0)
{
ret = sendglbdump(filename);
}
else if (stricmp(ext, "dkt") == 0)
{
ret = senddktdump(filename);
}
else
{
fprintf(stderr, "%s: cannot handle this file\n", filename);
return 0;
}
if (!ret)
return ret;
// check if korg answers
card->startinput();
unsigned char c;
for (int i = 0; i < 1000; i++)
if (card->hear(&c, 1) && c == 0xf0)
break;
if (c == 0xf0)
{
printf("korg answered: ");
int len = 0;
data[len++] = c;
while (len < sizeof(data) && card->hear(&c, 1) && c != 0xf7 && (kbhit() == 0 || getch() != 27))
data[len++] = c;
if (c == 0xf7)
data[len++] = c;
if (data[4] == 0x26)
printf("data format error\n");
else if (data[4] == 0x23)
printf("data load completed\n");
else
{
for (int i = 0; i < len; i++)
printf(" %02X", data[i]);
printf("\nsee korg manual for meaning of this system exclusive message\n");
}
}
else
fprintf(stderr, "no answer from korg\n");
card->stopinput();
return ret;
}
int iskorgext(char* ext)
{
if (stricmp(ext, "pcg") == 0)
return 1;
if (stricmp(ext, "sty") == 0)
return 1;
if (stricmp(ext, "arr") == 0)
return 1;
if (stricmp(ext, "bsq") == 0)
return 1;
if (stricmp(ext, "sng") == 0)
return 1;
return 0;
}
char glbfilename[128] = "";
char dktfilename[128] = "";
char pcgfilename[128] = "";
char styfilename[128] = "";
char arrfilename[128] = "";
char sngfilename[128] = "";
char bsqfilename[128] = "";
int main(int argc, char** argv)
{
argc--; argv++;
while (argc > 0 && **argv == '-')
{
fprintf(stderr, "invalid option %s\n", *argv);
argc--; argv++;
}
if (argc == 0)
{
printf("usage: sendi3 filename ...\n");
printf("files are korg i3 files (pcg, sty, arr, bsq, sng) or glb, drk\n");
printf("pcg\tkorg i3 programs\n");
printf("sty\tkorg i3 styles\n");
printf("arr\tkorg i3 arrangements\n");
printf("bsq\tkorg i3 backing sequences\n");
printf("sng\tkorg i3 songs\n");
printf("glb\tkorg i3 global settings\n");
printf("drk\tkorg i3 drumkit parameters\n");
printf("dos wildcards (*, ?) can be used\n");
return 1;
}
char* ext = getext(inputname);
if (!*ext)
{
fprintf(stderr, "filename %s has no extension\n", inputname);
return 0;
}
int ret = 0;
struct ffblk ff;
char fullname[128];
while (argc > 0 && **argv != '-')
{
char* filename = *argv++; argc--;
strcpy(fullname, filename);
inputname = fullname;
char* name = strrchr(fullname, '\\');
if (name)
name++;
else
{
name = strchr(fullname, ':');
if (name)
name++;
else
name = fullname;
}
int done = findfirst(fullname, & ff, 0);
if (done)
{
fprintf(stderr, "%s: no files found\n", inputname);
return 1;
}
while (done == 0)
{
strcpy(name, ff.ff_name);
strupr(fullname);
char* ext = getext(fullname);
if (strcmp(ext, "GLB") == 0)
{
if (*glbfilename != 0 && strcmp(fullname, glbfilename) != 0)
{
fprintf(stderr, "cannot send more than one global data (%s,%s)\n", fullname, glbfilename);
return 1;
}
strcpy(glbfilename, fullname);
}
else if (strcmp(ext, "DKT") == 0)
{
if (*dktfilename != 0 && strcmp(fullname, dktfilename) != 0)
{
fprintf(stderr, "cannot send more than one drumkit data (%s,%s)\n", fullname, dktfilename);
return 1;
}
strcpy(dktfilename, fullname);
}
else if (strcmp(ext, "PCG") == 0)
{
if (*pcgfilename != 0 && strcmp(fullname, pcgfilename) != 0)
{
fprintf(stderr, "cannot send more than one program data file (%s,%s)\n", fullname, pcgfilename);
return 1;
}
strcpy(pcgfilename, fullname);
}
else if (strcmp(ext, "STY") == 0)
{
if (*styfilename != 0 && strcmp(fullname, styfilename) != 0)
{
fprintf(stderr, "cannot send more than one style data file (%s,%s)\n", fullname, styfilename);
return 1;
}
strcpy(styfilename, fullname);
}
else if (strcmp(ext, "ARR") == 0)
{
if (*arrfilename != 0 && strcmp(fullname, arrfilename) != 0)
{
fprintf(stderr, "cannot send more than one arrangement data file (%s,%s)\n", fullname, arrfilename);
return 1;
}
strcpy(arrfilename, fullname);
}
else if (strcmp(ext, "BSQ") == 0)
{
if (*bsqfilename != 0 && strcmp(fullname, bsqfilename) != 0)
{
fprintf(stderr, "cannot send more than one backing sequence data file (%s,%s)\n", fullname, bsqfilename);
return 1;
}
strcpy(bsqfilename, fullname);
}
else if (strcmp(ext, "SNG") == 0)
{
if (*sngfilename != 0 && strcmp(fullname, sngfilename) != 0)
{
fprintf(stderr, "cannot send more than one song data file (%s,%s)\n", fullname, sngfilename);
return 1;
}
strcpy(sngfilename, fullname);
}
else
fprintf(stderr, "file %s ignored\n", fullname);
if (aborted)
break;
done = findnext(&ff);
}
}
card = detect_soundcard();
if (!card)
{
fprintf(stderr, "Could not detect soundcard\n");
return 1;
}
checkresponse();
if (*glbfilename)
{
int r = senddump(glbfilename);
if (r)
ret = r;
}
if (*dktfilename)
{
int r = senddump(dktfilename);
if (r)
ret = r;
}
if (*pcgfilename)
{
int r = senddump(pcgfilename);
if (r)
ret = r;
}
if (*styfilename)
{
int r = senddump(styfilename);
if (r)
ret = r;
}
if (*arrfilename)
{
int r = senddump(arrfilename);
if (r)
ret = r;
}
if (*bsqfilename)
{
int r = senddump(bsqfilename);
if (r)
ret = r;
}
if (*sngfilename)
{
int r = senddump(sngfilename);
if (r)
ret = r;
}
delete card;
return ret;
}